package com.zl.tby.service.impl;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.zl.tby.core.base.bean.TbyPageResult;
import com.zl.tby.core.base.util.HttpConnectionUtils;
import com.zl.tby.core.base.util.ToolsUtil;
import com.zl.tby.core.common.R;
import com.zl.tby.dto.TbyCommandCenterQuery;
import com.zl.tby.dto.TbySmartBoxCenterQuery;
import com.zl.tby.model.TbyCommandCenter;
import com.zl.tby.model.TbyConfigInfo;
import com.zl.tby.model.TbySmartBoxCenter;
import com.zl.tby.repository.TbySmartBoxCenterRepo;
import com.zl.tby.service.ITbyCommandCenterService;
import com.zl.tby.service.ITbyConfigInfoService;
import com.zl.tby.service.ITbySmartBoxCenterService;
import com.zl.tby.vo.box.SmartBoxDataResult;
import com.zl.tby.vo.box.SmartBoxDeviceInfo;
import com.zl.tby.vo.box.SmartBoxDeviceResult;
import lombok.extern.slf4j.Slf4j;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import org.noear.solon.data.annotation.Tran;
import org.noear.wood.IPage;
import org.noear.wood.annotation.Db;
import org.noear.wood.utils.StringUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 指挥中心和智能箱之间的关系
 * @author changpeng
 * @version 1.0
 * @since 2024/8/6 20:22
 */
@Slf4j
@Component
public class TbySmartBoxCenterServiceImpl implements ITbySmartBoxCenterService {

    @Db
    private TbySmartBoxCenterRepo tbySmartBoxCenterRepo;
    @Inject
    private ITbyCommandCenterService tbyCommandCenterService;
    @Inject
    private ITbyConfigInfoService tbyConfigInfoService;

    /**智能箱设备列表*/
    @Inject("${smart-box.device-list}")
    private String smartBoxDeviceList;
    @Inject("${smart-box.api-key}")
    private String serverApiKey;

    @Override
    @Tran
    public R<TbySmartBoxCenter> updateCenterId(Long id, Long centerId, String name, String ip, String longitude, String latitude) {
        TbySmartBoxCenter entity = this.get(id);
        boolean save = false;
        if (entity == null) {
            entity = new TbySmartBoxCenter();
            entity.setCreateBy(ToolsUtil.getLoginUserId());
            entity.setCreateTime(LocalDateTime.now());
            save = true;
        }
        entity.setCenterId(centerId);
        entity.setName(name);
        entity.setLongitude(longitude);
        entity.setLatitude(latitude);
        entity.setIp(ip);
        entity.setUpdateBy(ToolsUtil.getLoginUserId());
        entity.setUpdateTime(LocalDateTime.now());
        if (save) {
            long newId = tbySmartBoxCenterRepo.insert(entity, true);
            entity.setId(newId);
        } else {
            tbySmartBoxCenterRepo.updateById(entity, false);
        }
        return R.ok(entity);
    }

    @Override
    public TbySmartBoxCenter get(Long id) {
        return tbySmartBoxCenterRepo.selectById(id);
    }

    @Override
    public TbyPageResult<TbySmartBoxCenter> page(TbySmartBoxCenterQuery query) {
        IPage<TbySmartBoxCenter> iPage = tbySmartBoxCenterRepo.selectPage(query.getOffset(), query.getSize(), mp -> {
            mp.whereTrue()
                    .andIf(StringUtils.isNotEmpty(query.getName()), "name like ?", "%" + query.getName() + "%")
                    .andIf(query.getCenterId() != null, "center_id = ?", "%" + query.getCenterId() + "%");;
            if (StringUtils.isNotEmpty(query.getOrder())) {
                mp.orderBy(query.getOrder());
            }
        });
        return new TbyPageResult(iPage, query);
    }

    @Override
    public List<TbySmartBoxCenter> list(TbySmartBoxCenterQuery query) {
        return tbySmartBoxCenterRepo.selectList(mapperWhereQ -> {
            mapperWhereQ.whereTrue().andIf(StringUtils.isNotEmpty(query.getName()), "name like ?", "%" + query.getName() + "%")
                    .andIf(query.getCenterId() != null, "center_id = ?", "%" + query.getCenterId() + "%");;
            if (StringUtils.isNotEmpty(query.getOrder())) {
                mapperWhereQ.orderBy(query.getOrder());
            }
        });
    }

    @Override
    public TbyPageResult<TbySmartBoxCenter> boxPage(TbyCommandCenterQuery query) {
        String excludeIps = "";
        TbyConfigInfo configInfo = this.tbyConfigInfoService.getByCode("excludeSmartBoxIp");
        if (configInfo != null && StringUtils.isNotEmpty(configInfo.getContent())) {
            excludeIps = configInfo.getContent();
        }
        List<TbyCommandCenter> centerList = this.tbyCommandCenterService.list(new TbyCommandCenterQuery());
        Map<Long, String> centerIdToName = new HashMap<>(0);
        for (TbyCommandCenter center : centerList) {
            centerIdToName.put(center.getId(), center.getName());
        }
        List<TbySmartBoxCenter> dbList = this.list(new TbySmartBoxCenterQuery());
        Map<Long, Long> idToCenterId = new HashMap<>(0);
        for (TbySmartBoxCenter entity : dbList) {
            idToCenterId.put(entity.getId(), entity.getCenterId());
        }
        Map<String, String> headers = new HashMap<>();
        headers.put("apikey", serverApiKey);
        Map<String, String> params = new HashMap<>();
        params.put("pageSize", "500");
        params.put("pageNum", "0");
        List<TbySmartBoxCenter> resultList = new ArrayList<>();
        try {
            String response = HttpConnectionUtils.doGet(smartBoxDeviceList, params, headers);
            Gson gson = new Gson();
            SmartBoxDeviceResult result = gson.fromJson(response, new TypeToken<SmartBoxDeviceResult>(){}.getType());
            List<SmartBoxDeviceInfo> deviceList = result.getDevices();
            for (SmartBoxDeviceInfo device : deviceList) {
                if (excludeIps.indexOf("," + device.getIp() + ",") > -1) {
                    continue;
                }
                if (query.getName() != null && device.getName().indexOf(query.getName()) < 0) {
                    continue;
                }
                TbySmartBoxCenter entity = new TbySmartBoxCenter();
                entity.setId(device.getSn());
                entity.setName(device.getName());
                entity.setIp(device.getIp());
                if (device.getLocation() != null) {
                    entity.setLatitude(device.getLocation().getLatitude());
                    entity.setLongitude(device.getLocation().getLongitude());
                }
                if (idToCenterId.containsKey(entity.getId())) {
                    entity.setCenterId(idToCenterId.get(entity.getId()));
                    if (centerIdToName.containsKey(entity.getCenterId())) {
                        entity.setCenterName(centerIdToName.get(entity.getCenterId()));
                    }
                }
                resultList.add(entity);
            }
        } catch (Exception ex) {
            log.error("查询智能箱设备列表接口", ex);
        }
        Long total = ToolsUtil.toLong(resultList.size() + "", 0L);
        return new TbyPageResult(resultList, total, 1, resultList.size());
    }

    @Override
    public R<Void> saveBox(TbySmartBoxCenter form) {
        TbySmartBoxCenter entity = this.tbySmartBoxCenterRepo.selectById(form.getId());
        if (entity == null || entity.getId() == null) {
            if (form.getCenterId() == null) {
                return R.ok();
            }
            entity = new TbySmartBoxCenter();
            entity.setId(form.getId());
            entity.setCenterId(form.getCenterId());
            entity.setName(form.getName());
            entity.setLongitude(form.getLongitude());
            entity.setLatitude(form.getLatitude());
            entity.setId(form.getId());
            this.tbySmartBoxCenterRepo.insert(entity, true);
        } else {
            if (form.getCenterId() == null) {
                this.tbySmartBoxCenterRepo.deleteById(entity.getId());
                return R.ok();
            }
            entity.setCenterId(form.getCenterId());
            this.tbySmartBoxCenterRepo.updateById(entity, false);
        }
        return R.ok();
    }
}
